﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using Snowdreamist.ComponentModel;

namespace Snowdreamist.Collection
{
    public class ConcurrentObservableCollection<T> : ConcurrentCollection<T>, INotifyCollectionChanged, ICollection<T>, IList<T>
    {
        /// <summary>
        /// Default ctor
        /// </summary>
        public ConcurrentObservableCollection() : this(null) { }

        /// <summary>
        /// ctor
        /// </summary>
        /// <param name="items"></param>
        public ConcurrentObservableCollection(IEnumerable<T> items) : base(items) { }

        protected override void OnCollectionChanged(NotifyCollectionChangedAction action, T[] changedItems, int newIndex, int oldIndex)
        {
            base.OnCollectionChanged(action, changedItems, newIndex, oldIndex);

            if (this.CollectionChanged != null)
            {
                NotifyCollectionChangedEventArgs args = null;

                switch (action)
                {
                    case NotifyCollectionChangedAction.Add:
                        args = new NotifyCollectionChangedEventArgs(action, changedItems);
                        break;

                    case NotifyCollectionChangedAction.Move:
                        args = new NotifyCollectionChangedEventArgs(action, changedItems, newIndex, oldIndex);
                        break;

                    case NotifyCollectionChangedAction.Remove:
                        args = new NotifyCollectionChangedEventArgs(action, changedItems);
                        break;

                    case NotifyCollectionChangedAction.Replace:
                        if (changedItems.Length != 2)
                            throw new InvalidOperationException("Cannot notify replace");
                        args = new NotifyCollectionChangedEventArgs(action, changedItems[0], changedItems[1]);
                        break;

                    default:
                    case NotifyCollectionChangedAction.Reset:
                        args = new NotifyCollectionChangedEventArgs(action);
                        break;
                }

                this.CollectionChanged(this, args);
            }
        }

        public event NotifyCollectionChangedEventHandler CollectionChanged;
    }
}